import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart' as Foundation;
import 'package:logger/logger.dart';

const String GET = "get";
const String POST = "post";
const String PUT = "put";
const String DELETE = 'delete';
const String UPLOAD = 'upload';
// const String HOST = "https://www-api.86links.com/";

const int CONNECT_TIMEOUT = 60000;
const int RECEIVE_TIMEOUT = 60000;

typedef ErrorCallback = void Function(int count, String msg);

class HttpIOException implements Exception {
  String code;
  String message;

  HttpIOException(this.code, this.message);

  @override
  String toString() => 'HttpIOException(code: $code, message: $message)';
}

class HttpUtil {
  factory HttpUtil() => _httpInstance();
  static HttpUtil _instance;
  Dio _dio;
  Logger _logger = Logger();
  BaseOptions orgOption;
  // var bus = new EventBus();

  static HttpUtil _httpInstance() {
    if (_instance == null) {
      _instance = HttpUtil._init();
    }
    return _instance;
  }

  HttpUtil._init() {
    String platform = Platform.isIOS ? 'iOS' : 'Android';

    Map<String, dynamic> defaultHeaders = Map();
    defaultHeaders['Accept-Language'] = 'zh-cn';
    defaultHeaders['platform'] = platform;
    // defaultHeaders['appVersion'] = appConfig.appVersion;
    defaultHeaders['service'] = 'fst';
    orgOption = BaseOptions(
        contentType: 'application/json; charset=utf-8',
        connectTimeout: CONNECT_TIMEOUT,
        receiveTimeout: RECEIVE_TIMEOUT,
        headers: defaultHeaders);
    _dio = new Dio(orgOption);
  }

  //拦截器添加
  addInterceptor(Interceptor interceptor) {
    if (null != _dio) {
      _dio.interceptors.add(interceptor);
    }
  }

  clearIntercepters() {
    if (null != _dio) {
      _dio.interceptors.clear();
    }
  }

  //post
  Future<dynamic> post(String path, postData) {
    return request(path, POST, postData);
  }

  //post
  Future<dynamic> put(String path, postData) {
    return request(path, PUT, postData);
  }

  //get
  Future<dynamic> get(String path, [Map data]) {
    return request(path, GET, data);
  }

  Future<List<int>> downloadFile(String url) async {
    var response = await _dio?.get<List<int>>(
      url,
      options: Options(responseType: ResponseType.bytes),
    );
    return response.data;
  }

  Future<dynamic> exportFile(String url) async {
    var response = await _dio?.get<List<int>>(
      url,
      options: Options(responseType: ResponseType.bytes),
    );
    return response;
  }

  //get
  Future<dynamic> delete(String path) {
    return request(path, DELETE, null);
  }

  //get
  Future<dynamic> upload(String path, postData) {
    return request(path, UPLOAD, postData);
  }

  Future<dynamic> request(String path, String mode, postData) async {
    // await Future.delayed(Duration(seconds: 5), () {});

    try {
      switch (mode) {
        case GET:
          var getResponse = await _dio.get(path, queryParameters: postData);
          return new Future<dynamic>(() {
            return getResponse.data;
          });
        case DELETE:
          var getResponse = await _dio.delete(path);
          return new Future<dynamic>(() {
            return getResponse.data;
          });
        case POST:
          //做一层json 转换
          var postResponse =
              await _dio.post<dynamic>(path, data: json.encode(postData));
          return new Future<dynamic>(() {
            return postResponse.data;
          });
        case UPLOAD:
          var postResponse =
              await _dio.post<Map<String, dynamic>>(path, data: postData);
          return new Future<dynamic>(() {
            return postResponse.data;
          });
        case PUT:
          //做一层json 转换
          var postResponse =
              await _dio.put<dynamic>(path, data: json.encode(postData));
          return new Future<dynamic>(() {
            return postResponse.data;
          });
      }
    } on DioError catch (exception) {
      if (Foundation.kDebugMode) {
        _logger.e(''':::::::::接口请求出错::::::::
        PATH=> ${exception?.requestOptions?.path}
        DATA=> ${exception?.requestOptions?.data}
        QUERY=> ${exception?.requestOptions?.queryParameters}
        RESPONSE=> ${exception?.response?.data}
        ERROR=> $exception''');
      } else {
        // TalkingDataAppAnalytics.onEvent(
        //     eventID: 'apiError',
        //     eventLabel: exception?.request?.path ?? 'nopath',
        //     params: {
        //       'data': exception?.request?.data,
        //       'query': exception?.request?.queryParameters,
        //       'response': exception?.response?.data ?? '未接收到response',
        //     });
      }
      if (exception.response == null) {
        rethrow;
      }

      // 鉴权失败
      // if (exception.response.statusCode == 401) {
      //   bus.emit(EsEvents.RequestUnauthorized);
      // }

      if (exception.response.data != null &&
          exception.response.data is Map &&
          exception.response.data['error'] != null) {
        Map err = exception.response.data['error'];
        return new Future.error(
            new HttpIOException(err['code'], err['message']));
      }
      return new Future.error(new HttpIOException(
          exception.response.statusCode.toString(), exception.message));
    } catch (error) {
      return new Future.error(new HttpIOException('-2', error.toString()));
    }
    return new Future.error(new HttpIOException('-1', "not supported"));
  }
}
